#include "IndexTable.h"
#include "ManualHash.h"
#include "DocMatch.h"

#include <iostream>
#include <string>
#include <vector>
#include <map>

using namespace std;

IndexTable::IndexTable()
{
}

IndexTable::~IndexTable()
{
}

void IndexTable::IniciarTable(ifstream *wordCounterTableFile)
{
	if(wordCounterTableFile->is_open())
	{
//		uint doc;
//		ofstream out;
//		out.open("c://GetPagesFromFile.txt",ios::out);
		uint wordHash;
		*wordCounterTableFile >> wordHash;
		while(!wordCounterTableFile->eof())
		{
			// Read hashword
			*wordCounterTableFile >> wordHash;
						
			string pageMD5;
			*wordCounterTableFile >> pageMD5;
			map<string,DocMatch> MapDocMatch;
			while (pageMD5 != "0")
			{				
				uint amountHits;
				*wordCounterTableFile >> amountHits;
				DocMatch d(amountHits);
				
				MapDocMatch[pageMD5]=d;
				//cout << " Inseri " << d.matches.capacity() << " entradas no DocMatch de " << d.pageID << " para palavra " << hashword << endl; 
				// Le proximo doc
				*wordCounterTableFile >> pageMD5;
			}
			
			hashTable[wordHash] = MapDocMatch;
			cout << wordHash << " entradas : " << hashTable[wordHash].size() << endl;
		}
	}
}

void IndexTable::IniciarTable(WordCounterTable *counterTable)
{

	if(counterTable->wordCounterTable.size()!=0)
	{
		
		map<uint,vector<WordCounter> >::iterator counterTableIt;
		counterTableIt = counterTable->wordCounterTable.begin();
		for(;counterTableIt != counterTable->wordCounterTable.end();counterTableIt++)
		{
			uint hashword;
			hashword =counterTableIt->first;			
			map<string,DocMatch> MapDocMatch;
			
			vector<WordCounter>::iterator vectorWordCountIt;
			vectorWordCountIt = counterTableIt->second.begin();
			for(;vectorWordCountIt != counterTableIt->second.end();vectorWordCountIt++)
			{
				string pageMd5;
				pageMd5 = vectorWordCountIt->doc;
				uint amountHits;
				amountHits = vectorWordCountIt->n;
				DocMatch d(amountHits);
				MapDocMatch[pageMd5]=d;
			}
			hashTable[hashword] = MapDocMatch;
			cout << hashword << " entradas : " << hashTable[hashword].size() << endl;
		}		
	}
}

void IndexTable::InserirWord(string word,string doc,uint pos)
{
//	ofstream InserirWord;
//	InserirWord.open("C:\\InserirWord.txt",ios::app);
	
	uint hashWord = ManualHash::ToInteger(word);
	// Encontra
//	map<uint, map<uint,DocMatch> >::iterator mi;
	if(hashTable.find(hashWord)!= hashTable.end())
	{
		if(hashTable[hashWord].find(doc) != hashTable[hashWord].end())
		{
			(hashTable[hashWord])[doc].matches.push_back(pos);
		}
	}

//	InserirWord << hashWord;
//	InserirWord << " ";
	
/*	if (mi != hashTable.end() )
	{
		vector<DocMatch>::iterator vi;
		// n para log n?
		for(vi = mi->second.begin();vi!= mi->second.end();vi++)
		{
			if(vi->pageID == doc)
			{
				vi->matches.push_back(pos);
//				InserirWord << vi->pageID;
//				InserirWord << " ";
//				InserirWord << vi->matches.back();
//				InserirWord << endl;
				break;
			}
		}		
	} */	
}

void IndexTable::SalvarTable(ofstream* IndexTableFile)
{
	if(IndexTableFile->is_open())
	{		
	    //Percorre Map
		map<uint, map<string,DocMatch> >::iterator mi;		
		for (mi = hashTable.begin(); mi != hashTable.end(); mi++)
		{
			uint hashword = mi->first;
			*IndexTableFile << hashword;
			*IndexTableFile << " ";
			
			// Percorre Map<string,DocMatch>
		    map<string,DocMatch>::iterator vi;
			for(vi = mi->second.begin();vi != mi->second.end();vi++)
			{
				*IndexTableFile << vi->first;
				*IndexTableFile << " ";
				vector<ushort>::iterator di;
				di = vi->second.matches.begin();
				//Percorre Doc Match
				for (di = vi->second.matches.begin();di!=vi->second.matches.end();di++)
				{
					*IndexTableFile << *di;
					*IndexTableFile << " ";
				}
				*IndexTableFile << ", ";
			}		
		    *IndexTableFile << endl;
		}
	}
}
